package com.xy.smartsms.plugin;

import android.app.Activity;
import android.content.Context;
import android.text.TextUtils;

import com.xy.smartsms.data.BaseSmsPlugin;
import com.xy.smartsms.data.ISmsPlugin;
import com.xy.smartsms.data.PublicInfoData;
import com.xy.smartsms.data.SmsItem;
import com.xy.smartsms.util.Log;

import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import cn.cmcc.online.smsapi.sdk.action.AbsSdkDoAction;
import cn.cmcc.online.smsapi.sdk.constant.Constant;
import cn.cmcc.online.smsapi.sdk.net.NetUtil;
import cn.cmcc.online.smsapi.sdk.util.StringUtils;
import cn.cmcc.online.smsapi.ui.model.ActionData;
import cn.cmcc.online.smsapi.util.ParseBubbleManager;
import cn.cmcc.online.smsapi.util.ParseManager;
import cn.cmcc.online.smsapi.util.ParseRichBubbleManager;
import cn.cmcc.online.smsapi.util.ParseSmsMessage;
import cn.cmcc.online.smsapi.util.ParseSmsToBubbleUtil;
import cn.cmcc.online.smsapi.util.SdkCallBack;
import cn.cmcc.online.smsapi.util.SdkParamUtil;

public class XYSmsPlugin extends BaseSmsPlugin {
    private static final String TAG = XYSmsPlugin.class.getSimpleName();
    private static final String SUB_MENU = "secondmenu";
    private static final String ACTION_DATA = "action_data";
    private static final String MENU_NAME = "name";
    private static final String ACTION_TYPE = "Opentype";
    private static final String ACTION_URL = "Openurl";

    public XYSmsPlugin(Context context) {
        super(context);
    }

    public void finalize() throws Throwable {

    }

    private void setAction(JSONObject obj) {
        String actionString = obj.optString("NEW_ADACTION");
        if (TextUtils.isEmpty(actionString)) {
            return;
        }

        List<ActionData> actionList = new ArrayList<>();
        try {
            JSONArray array = new JSONArray(actionString);
            for (int i = 0; i < array.length(); i++) {
                JSONObject actionObj = (JSONObject) array.get(i);
                ActionData actionData = new ActionData(actionObj.optString("btn_name"),
                        actionObj.optString("action_type"),
                        actionObj.optString("action_data"));
                Map<String, String> extend = new HashMap<>();
                extend.put("group", actionObj.optString("groupValue"));
                actionData.setExtra(extend);

                actionList.add(actionData);
            }

            obj.put("action", actionList);
        } catch (Exception e) {
            e.printStackTrace();
        }

        return;
    }

    @Override
    public void init(Object doAction, Map<String, String> extend) {
        try {
            String channel = extend.get(Constant.CHANNEL);
            String iccid = extend.get(Constant.SIM_ICCID);
            ParseManager.initSdk(mContext, channel, iccid, true, true, extend);
            ParseManager.setSdkDoAction((AbsSdkDoAction) doAction);
        } catch (Throwable t) {
            Log.e(TAG, "init", t);
        }
    }

    @Override
    public void parseCard(final int type, final SmsItem item, final ISmsPluginCallback callback) {
        SdkCallBack sdkCallBack = new SdkCallBack() {
            @Override
            public void execute(Object... obj) {
                if (obj == null || obj.length < 4) {
                    cardCallback(callback, ISmsPlugin.STATUS_FAIL, type, null);
                    return;
                }

                String msgId = (String) obj[2];
                if (!msgId.equals(String.valueOf(item.getMsgId()))) {
                    Log.e(TAG, "execute: msgId mismatch, need:" + item.getMsgId() + " get:" + msgId);
                    cardCallback(callback, ISmsPlugin.STATUS_FAIL, type, null);
                    return;
                }

                JSONObject result = null;
                int status;
                int sdkStatus = (Integer) obj[0];
                Log.d(TAG, "execute: type=" + type + " status=" + sdkStatus);
                if (sdkStatus == ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_NEEDPARSE
                        || sdkStatus == ParseSmsMessage.DUOQU_CALLBACK_REFRESH_LIST
                        || sdkStatus == ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_SCOLLING) {
                    status = ISmsPlugin.STATUS_FAIL;
                } else if (sdkStatus == ParseSmsMessage.DUOQU_CALLBACK_UITHREAD_HASDATA
                        || sdkStatus == ParseSmsMessage.DUOQU_CALLBACK_BACKTHREAD_HASDATA) {
                    try {
                        switch ((Integer) obj[3]) {
                            case ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG:
                                result = (JSONObject) obj[1];
                                break;

                            case ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_SIMPLE_FLAG:
                                result = new JSONObject();
                                result.put("data", obj[1]);
                                break;

                            case ParseSmsMessage.DUOQU_SMARTSMS_SHOW_RECOGNISE_VALUE_FLAG:
                                result = (JSONObject) obj[1];
                                break;

                            case ParseSmsMessage.DUOQU_SMARTSMS_SHOW_URL_VALUE_FLAG:
                                result = (JSONObject) obj[1];
                                break;
                        }
                    } catch (Throwable t) {
                        Log.e(TAG, "parseMessage callback", t);
                    }

                    status = ISmsPlugin.STATUS_SUCCESS;
                } else {
                    status = ISmsPlugin.STATUS_SUCCESS;
                }

                if (result != null) {
                    setAction(result);
                    try {
                        result.put("sms_content", item.getBody());
                        result.put("msgId", item.getMsgId());
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                Log.i(TAG, "execute: " + result);
                cardCallback(callback, status, type, result);
            }
        };


        if (type == ISmsPlugin.TYPE_SENSITIVE) {

        } else {
            int flag;
            switch (type) {
                case ISmsPlugin.TYPE_SIMPLE:
                    flag = ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_SIMPLE_FLAG;
                    break;

                case ISmsPlugin.TYPE_FEATURE:
                    flag = ParseSmsMessage.DUOQU_SMARTSMS_SHOW_RECOGNISE_VALUE_FLAG;
                    break;

                case ISmsPlugin.TYPE_RICH:
                default:
                    flag = ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG;
                    break;
            }

            ParseSmsMessage.parseMessage(String.valueOf(item.getMsgId()),
                    item.getPhone(),
                    item.getCenter(),
                    item.getBody(),
                    item.getReceiveTime(),
                    flag,
                    null/*item.getExtend()*/,
                    sdkCallBack,
                    item.isScrolling());
        }
    }

    @Override
    public void parseCardSync(int type, SmsItem item) {

    }

    private JSONObject getActionData(String actionData) {
        if (TextUtils.isEmpty(actionData)) {
            return null;
        }

        String result;
        if (actionData.startsWith("{") && actionData.endsWith("}")) {
            result = actionData;
        } else {
            result = StringUtils.decode(actionData);
        }

        try {
            return new JSONObject(result);
        } catch (Throwable t) {
            Log.e(TAG, "getActionData", t);
        }

        return null;
    }

    private PublicInfoData buildMenu(String infoString) {
        PublicInfoData data = new PublicInfoData();
        data.manufacture = "XIAOYUAN";
        data.json = infoString;
        if (TextUtils.isEmpty(infoString)) {
            return data;
        }

        List<PublicInfoData.MenuItem> menuItemList = new ArrayList<PublicInfoData.MenuItem>();
        try {
            JSONArray array = new JSONArray(infoString);
            for (int menuIndex = 0; menuIndex < array.length(); menuIndex++) {
                JSONObject menuObj = array.getJSONObject(menuIndex);
                PublicInfoData.MenuItem menuItem = new PublicInfoData.MenuItem();
                menuItem.name = menuObj.optString(MENU_NAME);

                JSONArray subArray = menuObj.optJSONArray(SUB_MENU);
                if (subArray != null && subArray.length() > 0) {
                    List<PublicInfoData.SubMenuItem> subMenuItemList = new ArrayList<PublicInfoData.SubMenuItem>();
                    for (int subMenuIndex = 0; subMenuIndex < subArray.length(); subMenuIndex++) {
                        PublicInfoData.SubMenuItem subMenuItem = new PublicInfoData.SubMenuItem();
                        JSONObject subMenuObj = subArray.getJSONObject(subMenuIndex);
                        subMenuItem.name = subMenuObj.optString(MENU_NAME);
                        subMenuItem.json = getActionData(subMenuObj.opt(ACTION_DATA).toString())
                                .put("ManufactureData", "XIAOYUAN");

                        subMenuItemList.add(subMenuItem);
                    }

                    menuItem.subMenuList = subMenuItemList;
                } else {
                    menuItem.json = getActionData(menuObj.opt(ACTION_DATA).toString())
                            .put("ManufactureData", "XIAOYUAN");
                }

                menuItemList.add(menuItem);
            }

            data.menuList = menuItemList;
        } catch (Throwable t) {
            Log.e(TAG, "buildMenu", t);
        }

        return data;
    }

    // public info except menu
    private void loadExtraPublicInfo(final String phone, final PublicInfoData data, final ISmsPluginCallback callback) {
        SdkCallBack sdkCallBack = new SdkCallBack() {

            @Override
            public void execute(Object... obj) {
                try {
                    if (obj == null || obj.length <= 2) {
                        return;
                    }

                    String callbackPhone = (String) obj[2];
                    String result = (String) obj[1];
                    Integer status = (Integer) obj[0];

                    if (status == 0 && !StringUtils.isNull(result) && phone.equals(callbackPhone)) {
                        JSONObject json = new JSONObject(result);
                        data.extend = result;
                        data.name = json.optString("name");
                        String logo = json.optString("logoc");
                        if (!TextUtils.isEmpty(logo)) {
                            data.logo = NetUtil.BIZPORT_DOWN_URL + logo;
                        }
                    }

                    publicInfoCallback(callback, ISmsPlugin.STATUS_SUCCESS, data);
                } catch (Throwable t) {
                    Log.e(TAG, "execute loadExtraPublicInfo", t);
                }
            }
        };

        Map<String, String> extend = new HashMap<String, String>();
        extend.put("id", phone);
        ParseManager.queryPublicInfoWithId(mContext, phone, 1, "", extend, sdkCallBack);
    }

    private void handleSimChangeAndLocation() {
    }

    @Override
    public void parsePublicInfo(String phone, final Map<String, String> extend, final ISmsPluginCallback callback) {
        handleSimChangeAndLocation();

        final String formatNumber = StringUtils.getPhoneNumberNo86(phone);
        final String infoString = ParseManager.queryMenuByPhoneNum(Constant.getContext(), formatNumber, 1, null, extend, new SdkCallBack() {
            @Override
            public void execute(Object... dataArr) {
                Log.d(TAG, "execute: enter");
                if (callback == null) {
                    return;
                }

                String result = null;
                if (dataArr != null && dataArr.length > 0) {
                    try {
                        result = String.valueOf(dataArr[0]);
                    } catch (Throwable t) {
                        Log.e(TAG, "parsePublicInfo", t);
                    }
                }

                Log.d(TAG, "execute: result=" + result);
                PublicInfoData data = buildMenu(result);
                if (extend != null && extend.containsKey("public_info_full")) {
                    loadExtraPublicInfo(formatNumber, data, callback);
                } else {
                    publicInfoCallback(callback, ISmsPlugin.STATUS_SUCCESS, data);
                }
            }
        });

        // sometimes no callback from api, so callback using the return value
        if (TextUtils.isEmpty(infoString) && callback != null) {
            publicInfoCallback(callback, ISmsPlugin.STATUS_SUCCESS, buildMenu(infoString));
        }
    }

    @Override
    public void processAction(Activity activity, String action, Map<String, String> extend) {
        try {
            ParseManager.doAction(activity, action, extend);
        } catch (Throwable t) {
            Log.e(TAG, "processAction", t);
        }
    }

    @Override
    public void backgroundParse(String phoneNum, int limit) {
        if (TextUtils.isEmpty(phoneNum)) {
            ParseSmsToBubbleUtil.beforeHandParseReceiveSms(limit,
                    ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG | ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_SIMPLE_FLAG);
        } else {
            ParseSmsToBubbleUtil.beforeHandParseReceiveSms(phoneNum,
                    limit,
                    ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_RICH_FLAG | ParseSmsMessage.DUOQU_SMARTSMS_SHOW_BUBBLE_SIMPLE_FLAG,
                    true);
        }
    }

    @Override
    public void loadCache(String phone) {
        ParseBubbleManager.loadBubbleDataByPhoneNum(phone);
    }

    @Override
    public void clearCache(String phone) {
        ParseBubbleManager.clearCacheBubbleData(phone);
        ParseRichBubbleManager.clearCacheBubbleData(phone);
    }

    @Override
    public void setParam(Map<String, String> extend) {
        Iterator<Map.Entry<String, String>> iterator = extend.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> entry = iterator.next();
            SdkParamUtil.setParamValue(mContext, entry.getKey(), entry.getValue());
        }
    }
}
